﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Security;
using System.Security.Permissions;
using Codeplex.SPCleanup.Job;

namespace Codeplex.SPCleanup.FeatureReceivers
{
    public class ListCleanupJobFeatureReceiver : SPFeatureReceiver
    {                                                
        // Constant JOB Parameters
        private const string JOBNAME = "Cleanup Job";                        
        private const string LEADLAGTIMEKEY = "LeadLagTime";
        private const string JOBINTERVALKEY = "JobInterval";
        private const string JOBSTARTDATETIMEKEY = "JobStartDateTime";

        // Private Variables
        private int JobInterval = 1440;
        private int LeadLagTime = 0;
        private DateTime JobStartDateTime;

        /// <summary>
        /// Keeping the default Implementation for SPFeatureReceiver virtual methods
        /// </summary>
        /// <param name="properties">Feature Receiver Properties</param>
        [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
        public override void FeatureInstalled(SPFeatureReceiverProperties properties)
        {
        }

        /// <summary>
        /// Enables the site for cleanup by adding the default values
        /// </summary>
        /// <param name="properties">Feature Receiver Properties</param>
        [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            // Read from feature.xml properties           
            JobInterval = Int32.Parse(properties.Feature.Properties[JOBINTERVALKEY].Value);
            LeadLagTime = Int32.Parse(properties.Feature.Properties[LEADLAGTIMEKEY].Value);
            JobStartDateTime = DateTime.Parse(properties.Feature.Properties[JOBSTARTDATETIMEKEY].Value);

            SPWebService spWebService = properties.Feature.Parent as SPWebService;

            if (null != spWebService)
            {                    
                CreateCleanupJob(spWebService);
            }          
        }

        /// <summary>
        /// Disables the site for cleanup by setting the enabled property to false
        /// </summary>
        /// <param name="properties">Feature Receiver Properties</param>
        [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            SPWebService spWebService = properties.Feature.Parent as SPWebService;

            if (null != spWebService)
            {
                SPJobDefinitionCollection jobs = spWebService.JobDefinitions;
                DeleteExistingJob(JOBNAME, jobs);
            }
        }

        /// <summary>
        /// Keeping the default Implementation for SPFeatureReceiver virtual methods
        /// </summary>
        /// <param name="properties">Feature Receiver Properties</param>
        [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
        public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
        {
        }      

        /// <summary>
        /// Schedule the Clean Up Job schedule
        /// </summary>
        /// <param name="spWebService">Web service object</param>
        private void CreateCleanupJob(SPWebService spWebService)
        {
            SPJobDefinitionCollection jobs = spWebService.JobDefinitions;

            // Delete the existing jobs
            DeleteExistingJob(JOBNAME, jobs);

            SPDailySchedule schedule = GetDailySchedule(JobStartDateTime); //GetMinuteSchedule(JobInterval, JobStartDateTime);
            CleanupJob cleanupJob = new CleanupJob(JOBNAME, LeadLagTime, spWebService);
            //set the schedule
            cleanupJob.Schedule = schedule;
            cleanupJob.Update();
        }

        /// <summary>
        /// Get the minute schedule
        /// </summary>
        /// <param name="jobInterval">Job Interval</param>
        /// <param name="jobStartDateTime">Job Start Date Time</param>
        /// <returns>SPMinuteSchudule object</returns>
        private SPMinuteSchedule GetMinuteSchedule(int jobInterval, DateTime jobStartDateTime)
        {
            SPMinuteSchedule schedule = new SPMinuteSchedule();
            schedule.BeginSecond = 0;
            schedule.NextOccurrence(jobStartDateTime);
            schedule.Interval = jobInterval;

            return schedule;
        }

        /// <summary>
        /// Get the daily schedule
        /// </summary>
        /// <param name="jobInterval">Job Interval</param>
        /// <param name="jobStartDateTime">Job Start Date Time</param>
        /// <returns>SPDailySchedule object</returns>
        private SPDailySchedule GetDailySchedule(DateTime jobStartDateTime)
        {
            SPDailySchedule schedule = new SPDailySchedule();
            
            schedule.BeginHour = jobStartDateTime.Hour;
            schedule.BeginMinute = jobStartDateTime.Minute;
            schedule.BeginSecond = jobStartDateTime.Second;

            schedule.EndHour = jobStartDateTime.Hour;
            schedule.EndMinute = jobStartDateTime.Minute + 5;
            schedule.EndSecond = jobStartDateTime.Second;
            
            return schedule;
        }

        /// <summary>
        /// Delete the existing jobs from Sharepoint
        /// </summary>
        /// <param name="jobName">Name of the job to delete</param>
        /// <param name="jobs">Existing Job collection</param>
        private static void DeleteExistingJob(string jobName, SPJobDefinitionCollection jobs)
        {
            // delete the job if it is already there.
            foreach (SPJobDefinition job in jobs)
            {
                if (job.Name.Equals(jobName, StringComparison.InvariantCultureIgnoreCase))
                {
                    job.Delete();
                    break;
                }
            }
        }
    }
}
